#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
//#include <opencv/highgui.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

using namespace cv;

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char **argv)
{
  /* Make Connection */
int sockfd, newsockfd, portno;
     socklen_t clilen;
     sockaddr_in serv_addr, cli_addr;
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
     listen(sockfd,1);
     clilen = sizeof(cli_addr);
     newsockfd = accept(sockfd, 
                 (struct sockaddr *) &cli_addr, 
                 &clilen);
     if (newsockfd < 0) 
          error("ERROR on accept");
  /* Done Connecting */

  Mat frame;
  cvNamedWindow( "result", CV_WINDOW_AUTOSIZE);
  clock_t start = clock();
  int frame_count = 0;
  int key = 0;
  while( key != 'q'){
    /* get a frame */
    frame_count++;
    
    int* size = new int;
    read(newsockfd,size,sizeof(int));
    printf("*size: %i\n",*size);
    int bytes_read = 0;
    char* message = new char[*size];
    while(bytes_read < *size) {
      int increment = read(newsockfd,message+bytes_read,*size-bytes_read);
      if(increment == -1) {
        error("ERROR reading");
        return 1;
      }
      bytes_read += increment;
    }
    vector<uchar> buf;
    for(int c=0;c<*size;c++) {
      buf.push_back((uchar)message[c]);
    }
    
    frame = imdecode(buf,1);

    /* always check */
    //if (!frame) break;

    /* display current frame */
    imshow("result", frame);
    //cvShowImage( "result", frame);

    /* exit if user press 'q' */
    key = cvWaitKey(1);
    //    printf("Frame Count: %d\n", frame_count);
    printf("%f\n", ((double)CLOCKS_PER_SEC*frame_count/((clock() - start))));
    fflush(stdout);
  }

  /* free memory */
  cvDestroyWindow( "result" );

  close(newsockfd);
     close(sockfd);
  return 0;
}
